1. 题目描述(中等难度)

[warning] 222. 完全二叉树的节点个数

2. 解法一:递归

递归遍历二叉树,统计节点个数

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int countNodes(TreeNode root) {
     List<Integer> list = new ArrayList<>();
     preOrder(root,list);
     return list.size();
    }

    public void preOrder(TreeNode root,List<Integer> list){
        if(root == null){
            return;
        }
        list.add(root.val);
        preOrder(root.left,list);
        preOrder(root.right,list);
    }
}

简单递归实现

public int countNodes(TreeNode root) {
    if (root == null){
        return 0;
    }
    return countNodes(root.left) + countNodes(root.right) + 1;
}

3. 解法二:迭代

使用栈进行迭代

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int countNodes(TreeNode root) {
      List<Integer> res = new ArrayList<>();
      Deque<TreeNode> deque = new ArrayDeque<>();
      while(!deque.isEmpty() || root != null){
          while(root != null){
              res.add(root.val);
              deque.offerLast(root);
              root = root.left;
          }
         root =  deque.pollLast();
         root = root.right;
      }
      return res.size();
    }
}

4. 解法三:迭代+位运算

递归与迭代时间复杂度不太理想,进阶采用更快的时间复杂度解决,根据完成二叉树的性质解决问题。

完全二叉树定义:它是一棵空树或者它的叶子节点只出在最后两层,若最后一层不满则叶子节点只在最左侧。

满二叉树的节点个数计算方式:层数h, 则节点个数为 2^h - 1

对 root 节点的左右子树进行高度统计,分别记为 left 和 right,有以下两种结果

  • left == right。这说明,左子树一定是满二叉树,因为节点已经填充到右子树了,左子树必定已经填满了。所以左子树的节点总数我们可以直接得到,是 2^left - 1,加上当前这个 root 节点,则正好是 2^left。再对右子树进行递归统计。
  • left != right。说明此时最后一层不满,但倒数第二层已经满了,可以直接得到右子树的节点个数。同理,右子树节点 +root 节点,总数为 2^right。再对左子树进行递归查找。

二叉树的层数计算方式

    private int countLevel(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return Math.max(countLevel(root.left), countLevel(root.right)) + 1;
    }

二叉树左子树或右子树层数计算

    public int countLevel(TreeNode root){
        int level = 0;
        while(root != null){
            level++;
            root = root.left;
        }
        return level;
    }

注意: 1<<left 是 (int)Math.pow(2,leftLevel)的高级写法,2^left 次方。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int countNodes(TreeNode root) {
       if(root == null){
           return 0;
       }
      int leftLevel = level(root.left);
      int rightLevel = level(root.right);
      if(leftLevel == rightLevel){
          return (int)Math.pow(2,leftLevel) + countNodes(root.right);
      }
      else{
          return (int)Math.pow(2,rightLevel) + countNodes(root.left);
      }
    }
    public int level(TreeNode root){
        int count = 0;
        while(root != null){
            count++;
            root = root.left;
        }
        return count;
    }
}
© gaohueric all right reserved,powered by Gitbook文件修订时间: 2021-12-08 23:22:22

results matching ""

    No results matching ""